package com.gale.park.modules.pms.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gale.park.common.service.RedisService;
import com.gale.park.modules.pms.dto.FixedConditionDTO;
import com.gale.park.modules.pms.dto.FixedDTO;
import com.gale.park.modules.pms.mapper.PmsFixedMapper;
import com.gale.park.modules.pms.model.PmsCard;
import com.gale.park.modules.pms.model.PmsFixed;
import com.gale.park.modules.pms.model.PmsSeat;
import com.gale.park.modules.pms.service.PmsCardService;
import com.gale.park.modules.pms.service.PmsFixedService;
import com.gale.park.modules.pms.service.PmsSeatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Gale
 * @since 2022-02-16
 */
@Service
public class PmsFixedServiceImpl extends ServiceImpl<PmsFixedMapper, PmsFixed> implements PmsFixedService {

    @Autowired
    private PmsCardService cardService;
    @Autowired
    private PmsSeatService seatService;
    @Value("${redis.key.prefix.fixed}")
    private static String REDIS_KEY_PREFIX_FIXED_ID;

    @Autowired
    private RedisService redisService;

    @Override
    public Page<FixedDTO> list(FixedConditionDTO condition) {
        LambdaQueryWrapper<PmsFixed> queryWrapper = new LambdaQueryWrapper<>();

        if (StrUtil.isNotBlank(condition.getCardId())) {
            queryWrapper.eq(PmsFixed::getCardId, condition.getCardId());
        }

        // 获取到固定车主的信息
        List<PmsFixed> pmsFixeds = baseMapper.selectList(queryWrapper);

        List<FixedDTO> records = new ArrayList<>();

        // 封装数据
        for (PmsFixed fixed : pmsFixeds) {
            FixedDTO fixedDTO = new FixedDTO();
            // 获取IC卡的信息
            PmsCard card = cardService.getCarById(fixed.getCardId());
            if(card == null) continue;

            PmsSeat seat = seatService.getSeatById(card.getSeatId());
            fixedDTO.setSeatState(seat.getSeatState());
            fixedDTO.setCardId(card.getCardId());
            fixedDTO.setCardNum(card.getCarNum());
            fixedDTO.setUserName(card.getUserName());

            fixedDTO.setEntryDate(fixed.getEntryDate());
            fixedDTO.setEntryTime(fixed.getEntryTime());
            fixedDTO.setOutDate(fixed.getOutDate());
            fixedDTO.setOutTime(fixed.getOutTime());
            fixedDTO.setFixedId(fixed.getFixedId());
            fixedDTO.setStatus(fixed.getStatus());

            records.add(fixedDTO);
        }


        Page<FixedDTO> page = new Page<>(condition.getPageNum(), condition.getPageSize(), records.size());
        page.setRecords(records);

        return page;
    }


    @Override
    @Transactional
    public boolean entryParking(String cardId) {
        PmsCard card = cardService.getCarById(cardId);
        seatService.updateStatus(card.getSeatId(), 1);
        PmsFixed fixed = new PmsFixed();
        fixed.setCardId(cardId);
        fixed.setFixedId(getNum());
        fixed.setEntryDate(new Date());
        fixed.setEntryTime(new Date());
        fixed.setStatus(0);
        return this.save(fixed);
    }

    @Override
    @Transactional
    public boolean outParking(String fixedId) {

        QueryWrapper<PmsFixed> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PmsFixed::getFixedId, fixedId);

        PmsFixed fixed = baseMapper.selectOne(queryWrapper);
        // 获取IC卡信息
        PmsCard card = cardService.getCarById(fixed.getCardId());
        // 修改车位状态
        seatService.updateStatus(card.getSeatId(), 0);

        fixed.setOutDate(new Date());
        fixed.setOutTime(new Date());
        fixed.setStatus(1);

        UpdateWrapper<PmsFixed> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(PmsFixed::getFixedId, fixed.getFixedId());
        return this.update(fixed, updateWrapper);
    }

    @Override
    public boolean deleteById(String fixedId) {
        UpdateWrapper<PmsFixed> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .eq(PmsFixed::getFixedId, fixedId);

        return this.remove(updateWrapper);
    }

    /**
     * 生成编号：生成规则:8位日期+6位以上自增id；
     *
     * @return
     */
    public String getNum() {
        // 编号
        StringBuilder sb = new StringBuilder();
        // 8位日期
        String yyyyMMdd = new SimpleDateFormat("yyyyMMdd").format(new Date());
        sb.append(yyyyMMdd);

        // 6位以上自增id
        // redis incr 原子性
        // 适合并发的自增方式：
        String key = REDIS_KEY_PREFIX_FIXED_ID + yyyyMMdd;
        Long incr = redisService.incr(key, 1);
        // 拿到当前的6位以上自增 如果小于6位，自动补全3
        if (incr.toString().length() <= 6) {
            sb.append(String.format("%06d", redisService.incr(key, 1)));
        } else {
            // 如果是6位 不用补0
            sb.append(incr);
        }
        return sb.toString();
    }
}
